# Title     : TODO
# Objective : TODO
# Created by: Administrator
# Created on: 2019/7/24

library(ggrepel)
library(ropls)
library(pROC)
library(egg)
library(randomForest)
library(Boruta)
library(magrittr)
library(e1071)
library(optparse)
library(tidyverse)
library(DMwR)

createWhenNoExist <- function(f) {
  !dir.exists(f) && dir.create(f)
}

option_list <- list(
  make_option("--i", default = "../train.csv", type = "character", help = "metabolite data file"),
  make_option("--g", default = "../train_group.csv", type = "character", help = "sample group file"),
  make_option("--sc", default = "sample_color.txt", type = "character", help = "sample color file"),
  make_option("--config", default = "../calculate_config.txt", type = "character", help = "config file")

)
opt <- parse_args(OptionParser(option_list = option_list))

options(digits = 3)
args <- commandArgs(trailingOnly = F)
scriptPath <- dirname(sub("--file=", "", args[grep("--file", args)]))
source(str_c(scriptPath, "/base.R"))

configData <- read_tsv(opt$config, col_names = F) %>%
  set_colnames(c("arg", "value"))

kernel <- configGet(configData, "kernel")
cost <- configGet(configData, "cost") %>%
  as.numeric()
tolerance <- configGet(configData, "tolerance") %>%
  as.numeric()
epsilon <- configGet(configData, "epsilon") %>%
  as.numeric()
gamma <- configGet(configData, "gamma") %>%
  as.numeric()
coef0 <- configGet(configData, "coef0") %>%
  as.numeric()
degree <- configGet(configData, "degree") %>%
  as.numeric()

sampleInfo <- read_csv(opt$g) %>%
  rename(ClassNote = Group) %>%
  select(c("SampleID", "ClassNote")) %>%
  mutate(ClassNote = as.character(ClassNote))

groups <- sampleInfo %>%
  .$ClassNote %>%
  unique()

parent <- paste0("./")
createWhenNoExist(parent)
originalData <- read_csv(opt$i) %>%
  rename(Metabolite = SampleID) %>%
  gather("SampleID", "Value", -Metabolite) %>%
  spread(Metabolite, "Value")
originalColumnNames <- colnames(originalData)

data <- originalData %>%
  inner_join(sampleInfo, by = c("SampleID")) %>%
  mutate(ClassNote = factor(ClassNote, levels = unique(ClassNote)))

trainData <- data %>%
  column_to_rownames("SampleID")

hasExternal <- configGet(configData, "hasExternal") %>%
  as.logical()

testSampleInfoTb <- if (hasExternal) {
  read_csv(str_c("../test_group.csv"))
}else {
  read_tsv(str_c("../../preprocess_0/test_group.txt"))
}
testSampleInfo <- testSampleInfoTb %>%
  rename(ClassNote = Group) %>%
  select(c("SampleID", "ClassNote")) %>%
  filter(ClassNote %in% groups)
testDataTb <- read_csv("../test.csv")
testData <- testDataTb %>%
  rename(Metabolite = SampleID) %>%
  gather("SampleID", "Value", -Metabolite) %>%
  spread(Metabolite, "Value") %>%
  select(originalColumnNames) %>%
  inner_join(testSampleInfo, by = c("SampleID")) %>%
  column_to_rownames("SampleID")

head(trainData)

numColumns <- colnames(trainData) %>%
  keep(function(x) {
    startsWith(x, "Nubmer") || startsWith(x, "Number")
  })

trainData <- trainData %>%
  mutate_at(vars(numColumns), as.numeric) %>%
  mutate_at(vars(-numColumns), factor)

print("===")

x <- trainData %>% select(-c("ClassNote"))
y <- trainData$ClassNote
finalGamma <- if (is.na(gamma)) {
  if (is.vector(x)) 1 else 1 / ncol(x)
}else {
  gamma
}

x <- x %>%
  mutate_at(vars(numColumns), as.numeric) %>%
  mutate_at(vars(-numColumns), factor) %>%
  mutate_all(as.numeric)

svmRs <- svm(x, y, type = 'C', kernel = kernel, cost = cost, tolerance = tolerance, epsilon = epsilon,
             gamma = finalGamma, coef0 = coef0, degree = degree, probability = T, scale = F)
print("===")
svDf <- svmRs$SV %>%
  as.data.frame() %>%
  rownames_to_column("SampleID") %>%
  as_tibble()
svDf
write_csv(svDf, "SV.csv")

testDf <- testData %>%
  select(-c("ClassNote")) %>%
  mutate_at(vars(numColumns), as.numeric) %>%
  mutate_at(vars(-numColumns), factor) %>%
  mutate_all(as.numeric) %>%
  as.data.frame()
predData <- predict(svmRs, newdata = testDf, probability = F)
prob <- predict(svmRs, testDf, probability = T)
probDf <- prob %>%
  attr(., "probabilities") %>%
  as.data.frame() %>%
  rownames_to_column("SampleID")
predDf1 <- probDf %>%
  rowwise() %>%
  do({
    result <- as.data.frame(.)
    values <- result[1,] %>%
      select(-c("SampleID")) %>%
      unlist()
    result$Value <- values[1]
    result
  }) %>%
  select(c("SampleID", "Value")) %>%
  add_column(Prediction = predData)
predictFinalDf1 <- testSampleInfo %>%
  left_join(predDf1, by = c("SampleID"))
write_tsv(predictFinalDf1, "Classification_Result.txt")

predDf <- probDf %>%
  rowwise() %>%
  do({
    result <- as.data.frame(.)
    values <- result[1,] %>%
      select(-c("SampleID")) %>%
      unlist()
    result$Probability <- max(values)
    result
  }) %>%
  select(c("SampleID", "Probability")) %>%
  add_column(Prediction = predData)
predictFinalDf <- testSampleInfo %>%
  left_join(predDf, by = c("SampleID")) %>%
  rename(Sample = SampleID) %>%
  select(-c("Probability"), "Probability")
write_csv(predictFinalDf, "SVM_Prediction.csv")

imp <- (t(svmRs$coefs) %*% svmRs$SV)[1,]^2
names(imp) <- colnames(x);
impData <- imp %>%
  as.data.frame() %>%
  rownames_to_column("Metabolite") %>%
  as_tibble() %>%
  set_colnames(c("Metabolite", "Value")) %>%
  arrange(Value) %>%
  mutate(Metabolite = factor(Metabolite, levels = unique(Metabolite)))

plotData <- impData
outData <- plotData %>%
  arrange(desc(Value)) %>%
  rename(`SVM-RFE` = Value)
outFileName <- paste0(parent, "/SVM_VarImp.csv")
write_csv(outData, outFileName)

pClassNote <- predictFinalDf$ClassNote %>%
  as.factor()
pPrediction <- predictFinalDf$Prediction %>%
  as.factor() %>%
  factor(., levels = levels(pClassNote))

pre_summary = table(pClassNote, pPrediction)

summaryTb <- pre_summary %>%
  as.data.frame() %>%
  as_tibble() %>%
  rename(Var1 = 1, Var2 = 2) %>%
  spread(Var2, "Freq")
summaryMatrix <- summaryTb %>%
  select(-"Var1") %>%
  as.matrix()
diagSum <- sum(diag(summaryMatrix))
sum <- sum(summaryMatrix)
predictive <- (diagSum / sum) %>%
  round(3)
finalSummaryTb <- summaryTb %>%
  mutate(`Model predictive accuracy` = c(predictive, "")) %>%
  rename(` ` = Var1)
finalSummaryTb

write_csv(finalSummaryTb, "SVM_Prediction_Summary.csv")






